# -*- coding: utf-8 -*-

from datetime import datetime
import re, urllib2

import matematyka

class Info:
    u"""Informacje i autorzy"""
    def __init__(self):
        self.re = re.compile(r'^info( |).*')

    def __repr__(self):
        return "info"
    
    def wykonaj(self, dane):
        return u"\n".join((u"Autorzy:",
                          u"Kod bota: Adam \"Dodek\" Michalik <dodekam@gmail.com>",
                          u"Wiele funkcji: Jędrzej \"Coldpeer\" Czarnecki <coldpeer@gmail.com>",
                          u"Cały kod jest na GPL więc jeżeli ktoś zainteresowany to niech wyśle mi e-maila."))
class Bash:
    u"""Losowy cytat z basha"""
    def __init__(self):
        self.re = re.compile(r'^bash(.*)')

    def __repr__(self):
        return "bash"

    def wykonaj(self, dane):
        q = urllib2.urlopen("http://bash.org.pl/random")
        quote = re.findall( '<p class="quote">(.*?)</p>', q.read().decode('utf-8'), re.DOTALL)
        quote = quote[0].replace('&lt;', '<').replace('&gt;', '>').replace('<br />', '\n').replace('&quot;', '"')
        try:
            quote.encode("cp1250") #nie wszystko, kurna, da się zapisać w cp
        except UnicodeDecodeError:
            return self.wykonaj(())
        return quote



class Powiedz:
    u"""Bot mówi co zechcesz!"""

    def __init__(self):
        self.re = re.compile(r'^(powiedz|say) (.*)')

    def __repr__(self):
        return "powiedz" #nazwa funkcji

    def wykonaj(self, dane):
        return dane[0][1]

class Dodaj:
    u"""Dodawanie dwóch liczb. Składnia: \"+ liczba1 liczba2\""""

    def __init__(self):
        self.re = re.compile(r'^\+ (\d+) (\d+)$')

    def __repr__(self):
        return "+" #nazwa funkcji

    def wykonaj(self, dane):
        dane = map(int, dane[0])
        return unicode(dane[0]+dane[1])

class Odejmij:
    u"""Odejmowanie dwóch liczb. Składnia: \"- liczba1 liczba2\""""

    def __init__(self):
        self.re = re.compile(r'^- (\d+) (\d+)$')

    def __repr__(self):
        return "-" #nazwa funkcji

    def wykonaj(self, dane):
        dane = map(int, dane[0])
        return unicode(dane[0]-dane[1])

class Pomnoz:
    u"""Mnozenie dwóch liczb. Składnia: \"* liczba1 liczba2\""""

    def __init__(self):
        self.re = re.compile(r'^\* (\d+) (\d+)$')

    def __repr__(self):
        return "*" #nazwa funkcji

    def wykonaj(self, dane):
        dane = map(int, dane[0])
        return unicode(dane[0]*dane[1])

class Podziel:
    u"""Dzielenie dwóch liczb. Składnia: \"/ liczba1 liczba2\""""

    def __init__(self):
        self.re = re.compile(r'^/ (\d+) (\d+)$')

    def __repr__(self):
        return "/" #nazwa funkcji

    def wykonaj(self, dane):
        dane = map(float, dane[0])
        if dane[1] != 0:
            return unicode(dane[0]/dane[1])    
        else:
            return u"Nie nauczyli, że przez zero się nie dzieli?"
class Help:
    u"""Blah, nie wiesz, jak się korzysta z pomocy?"""

    def __init__(self, funkcje):
        self.re = re.compile(r'^(help|pomoc)( |)(.*)')
        self.funkcje = funkcje
    def __repr__(self):
        return "help"

    def wykonaj(self, dane):
        if dane[0][2]:
            if self.funkcje.has_key(dane[0][2]):
                return self.funkcje[dane[0][2]].__doc__
        else:
            funkcje = u""
            for funkcja in self.funkcje:
                funkcje += funkcja+", "

            funkcje = funkcje[:-1]
            return u"Znam następujące polecenia: "+funkcje+u". Jeżeli chcesz się dowiedzieć więcej o danym poleceniu, wpisz 'help nazwa_polecenia'"


class Rmf:
     u"""Piosenki, które aktualnie leciały/lecą/będą leciały w RMF FM."""
     def __init__(self):
         self.re = re.compile(r"^rmf.*")

     def __repr__(self):
         return "rmf"

     def wykonaj(self, data):
         try:
             s = urllib2.urlopen("http://static.rmf.pl/rmf_fm/info_exp.txt")
             s = urllib2.unquote(s.read().lower()).replace(u"<u>", u"").replace("</u>", "")

             reg = u"poprzednio - (.*?)</a>(.*?)teraz - (.*?)</a>(.*?)" + \
                   u"za chwile - (.*?)</a>(.*?)nastepnie - (.*?)</a>"

             if re.search("teraz", s):
                 m = re.findall(reg, s)[0]
                 return u"Poprzednio - " + m[0] + u"\nTeraz - " + m[2] + u"\nZa chwilę - " + m[4] + u"\nNastępnie - " + m[6]
             else:
                 return u"Obecnie nie są grane żadne utwory.";

         except urllib2.HTTPError, e:
             return u"Wystąpił błąd podczas próby połączenia się z serwerem RMF FM."


class Lotto:
     u"""Wyniki lotto z ostatnich losowań."""
     def __init__(self):
         self.re = re.compile(r"^lotto.*")
         self.data = re.compile(r"class=\"gl2\">(.*?)</td>", re.DOTALL)
         self.lastCheck = None
         
     def __repr__(self):
         return "lotto"

     def wykonaj(self, data):
         if not self.lastCheck or self.lastCheck.day != datetime.now().day: #jeżeli dzień ostatniego sprawdzenia jest różny od aktualnego
             conn = urllib2.urlopen("http://www.lotto.csa.pl")
             s = conn.read().decode("iso-8859-2")
             conn.close()

             data = self.data.findall(s)[0]
             data = re.sub("(<(.*?)>|\t{2,})", "", data)

             self.cache = data
             self.lastCheck = datetime.now()
             return data
         else:
             return self.cache
    



class Licz:
    u"""Parsowanie wyrażeń matematycznych.
    Składnia: licz wyrażenie, np. licz (2+2)*2
    I mała informacja - wynik jest zwracany jako int jeżeli wszystkie dane są typu int, więc jeżeli chcesz mieć cyfry po przecinku to dodaj .0 do jakiejś cyfry - coś w stylu \"1.0/8.0\" zamiast \"1/8\""""
    def __init__(self):
        self.re = re.compile(u"licz (.*)")

    def __repr__(self):
        return "licz"

    def wykonaj(self, data):
        try:
            rd = unicode(matematyka.expr_eval(data[0]))
            return rd
        except ValueError:
            return u"Błąd składni"
        except ZeroDivisionError:
            return u"W szkole nie nauczyli, że przez zero się nie dzieli?"


powiedz = Powiedz()
dodaj = Dodaj()
odejmij = Odejmij()
pomnoz = Pomnoz()
podziel = Podziel()
bash = Bash()
rmf = Rmf()
lotto = Lotto()
info = Info()
licz = Licz()

funkcje = {}
help = Help(funkcje)

funkcje[repr(powiedz)] = powiedz
funkcje[repr(dodaj)] = dodaj
funkcje[repr(odejmij)] = odejmij
funkcje[repr(pomnoz)] = pomnoz
funkcje[repr(podziel)] = podziel
funkcje[repr(bash)] = bash
funkcje[repr(rmf)] = rmf
funkcje[repr(lotto)] = lotto
funkcje[repr(info)] = info
funkcje[repr(licz)] = licz
funkcje[repr(help)] = help


